using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WeaponMecanimWrapper : MonoBehaviour
{
	public enum AnimationType
	{
		OnlyShoot = 0,
		OnlyAltShoot = 1,
		ShootAndAltShoot = 2,
		RandomShoot = 3,
		AltShootHold = 4
	}

	private struct BonesPosition
	{
		public Vector3 position;

		public Quaternion rotation;
	}

	[HideInInspector]
	public bool needSeccondAttack;

	public Animator _animator;

	public Animator _animatorLeft;

	[Space(10f)]
	public AnimatorOverrideController overrideController;

	public AnimatorOverrideController overrideControllerFemale;

	public AnimatorOverrideController overrideControllerFPS;

	public RuntimeAnimatorController weaponOverrideControllerFPS;

	public AnimationType animationType;

	private bool _pullable;

	private float _timeBetweenShots;

	private float _reloadTime;

	private PlayerMecanimWrapper _mecanimWrapper;

	public int currentShootIndex;

	private bool needSeccondAnimation;

	private List<BonesPosition> bonesWeapon;

	private List<BonesPosition> bonesWeaponLeft;

	private RuntimeAnimatorController baseOverrideController;

	private bool isPlayerWeapon;

	public bool pullable
	{
		get
		{
			return _pullable;
		}
		set
		{
			_pullable = value;
		}
	}

	public bool isReloading
	{
		get
		{
			if (_animator != null)
			{
				return _animator.GetCurrentAnimatorStateInfo(0).IsName("Reload");
			}
			return false;
		}
	}

	public bool isEmpty
	{
		get
		{
			if (_animator != null)
			{
				return _animator.GetCurrentAnimatorStateInfo(0).IsName("Empty");
			}
			return false;
		}
	}

	private void Awake()
	{
		if (_animator != null)
		{
			_animator.logWarnings = false;
		}
		if (_animatorLeft != null)
		{
			_animatorLeft.logWarnings = false;
		}
	}

	private void Start()
	{
		BaseWeapon component = GetComponent<BaseWeapon>();
		component.AddEventListener(this, "NoAmmo", delegate
		{
			Empty();
		}, false);
		component.AddEventListener(this, "Reload", delegate
		{
			Reload();
		}, false);
		component.AddEventListener(this, "Shoot", delegate
		{
			Shoot();
		}, false);
		component.AddEventListener(this, "ChangeStrength", delegate(Object sender, object[] args)
		{
			float chargeMultipler = (float)args[0];
			SetChargeMultipler(chargeMultipler);
		}, false);
		component.AddEventListener(this, "StartShoot", delegate
		{
			ShootHold(true);
		}, false);
		component.AddEventListener(this, "StopShoot", delegate
		{
			ShootHold(false);
		}, false);
	}

	private void OnDestroy()
	{
		Unsubscribe();
	}

	private void OnEnable()
	{
		if (_animator != null)
		{
			CalculateAnimationSpeed(_reloadTime, _timeBetweenShots);
		}
	}

	private void OnDisable()
	{
		if (!isPlayerWeapon || !(_animator != null) || bonesWeapon == null)
		{
			return;
		}
		SkinnedMeshRenderer componentInChildren = _animator.GetComponentInChildren<SkinnedMeshRenderer>();
		if (componentInChildren != null)
		{
			for (int i = 0; i < componentInChildren.bones.Length; i++)
			{
				componentInChildren.bones[i].localPosition = bonesWeapon[i].position;
				componentInChildren.bones[i].localRotation = bonesWeapon[i].rotation;
			}
		}
		if (!(_animatorLeft != null) || bonesWeaponLeft == null || bonesWeaponLeft != null)
		{
			return;
		}
		componentInChildren = _animatorLeft.GetComponentInChildren<SkinnedMeshRenderer>();
		if (componentInChildren != null)
		{
			for (int j = 0; j < componentInChildren.bones.Length; j++)
			{
				componentInChildren.bones[j].localPosition = bonesWeaponLeft[j].position;
				componentInChildren.bones[j].localRotation = bonesWeaponLeft[j].rotation;
			}
		}
	}

	public void Unsubscribe()
	{
		if (_mecanimWrapper != null)
		{
			_mecanimWrapper.eventHoldShoot -= ShootHold;
			_mecanimWrapper.eventAimMode -= SwitchAim;
		}
	}

	public void Shoot()
	{
		string animationName = string.Empty;
		switch (animationType)
		{
		case AnimationType.OnlyShoot:
			animationName = "WeaponShoot";
			break;
		case AnimationType.OnlyAltShoot:
			animationName = "WeaponShootAlt";
			break;
		case AnimationType.ShootAndAltShoot:
			if (needSeccondAnimation)
			{
				animationName = "WeaponShootAlt";
				needSeccondAnimation = false;
			}
			else
			{
				animationName = "WeaponShoot";
				needSeccondAnimation = true;
			}
			break;
		case AnimationType.RandomShoot:
			animationName = ((Random.Range(0, 2) <= 0) ? "WeaponShoot" : "WeaponShootAlt");
			break;
		case AnimationType.AltShootHold:
			if (needSeccondAnimation)
			{
				animationName = "WeaponShootAlt";
				break;
			}
			animationName = "WeaponShoot";
			_animator.SetBool("WeaponShootHold", true);
			needSeccondAttack = true;
			break;
		}
		if (needSeccondAttack)
		{
			ShootLeft(animationName);
			needSeccondAttack = false;
			return;
		}
		ShootRight(animationName);
		if (_animatorLeft != null)
		{
			needSeccondAttack = true;
		}
	}

	public void ShootLeft(string animationName)
	{
		if (_animatorLeft != null)
		{
			_animatorLeft.SetTrigger(animationName);
		}
		if (!(_mecanimWrapper == null) && !isReloading)
		{
			if (animationName == "WeaponShoot")
			{
				_mecanimWrapper.ShootLeft();
			}
			else
			{
				_mecanimWrapper.ShootLeftAlt();
			}
		}
	}

	public void ShootRight(string animationName)
	{
		if (_animator != null && !isReloading)
		{
			_animator.SetTrigger(animationName);
		}
		if (!(_mecanimWrapper == null) && !isReloading)
		{
			if (animationName == "WeaponShoot")
			{
				_mecanimWrapper.ShootRight();
			}
			else
			{
				_mecanimWrapper.ShootRightAlt();
			}
		}
	}

	public void Reload()
	{
		ShootHold(false);
		if (!isReloading)
		{
			if (_animator != null)
			{
				_animator.ResetTrigger("CancelWeaponReload");
				_animator.SetTrigger("WeaponReload");
			}
			if (_animatorLeft != null)
			{
				_animatorLeft.ResetTrigger("CancelWeaponReload");
				_animatorLeft.SetTrigger("WeaponReloadL");
			}
			if (!(_mecanimWrapper == null))
			{
				_mecanimWrapper.DeactivateShootTriggers();
				_mecanimWrapper.Reload();
			}
		}
	}

	public void CancelReload()
	{
		if (_animator != null)
		{
			_animator.SetTrigger("CancelWeaponReload");
		}
		if (_animatorLeft != null)
		{
			_animatorLeft.SetTrigger("CancelWeaponReloadL");
		}
		ShootHold(false);
		_mecanimWrapper.CancelReload();
	}

	public void Empty()
	{
		if (!isEmpty)
		{
			if (_animator != null)
			{
				_animator.SetTrigger("WeaponEmpty");
			}
			if (_animatorLeft != null)
			{
				_animatorLeft.SetTrigger("WeaponEmptyL");
			}
			if (!(_mecanimWrapper == null))
			{
				_mecanimWrapper.DeactivateShootTriggers();
				_mecanimWrapper.Empty();
			}
		}
	}

	public void SetChargeMultipler(float value)
	{
		_animator.SetFloat("WeaponPull", value);
		if (!(_mecanimWrapper == null))
		{
			_mecanimWrapper.SetWeaponPull(value);
		}
	}

	public void MeleeHit(bool isChainsaw)
	{
		if (_mecanimWrapper == null)
		{
			return;
		}
		if (isChainsaw)
		{
			if (_animator != null)
			{
				if (needSeccondAttack)
				{
					_animator.SetTrigger("WeaponShootAlt");
					_mecanimWrapper.ShootRightAlt();
					return;
				}
				_animator.SetTrigger("WeaponShoot");
				_mecanimWrapper.ShootRight();
				needSeccondAttack = true;
				_animator.SetBool("WeaponShootHold", true);
			}
		}
		else if (Random.Range(0, 2) > 0)
		{
			if (_animator != null)
			{
				_animator.SetTrigger("WeaponShoot");
			}
			_mecanimWrapper.ShootRightAlt();
		}
		else
		{
			if (_animator != null)
			{
				_animator.SetTrigger("WeaponShoot");
			}
			_mecanimWrapper.ShootRight();
		}
	}

	public void ShootHold(bool value)
	{
		if (_animator != null)
		{
			_animator.SetBool("WeaponShootHold", value);
		}
		if (_animatorLeft != null)
		{
			_animatorLeft.SetBool("WeaponShootHold", value);
		}
		if (!value)
		{
			if (_animator != null)
			{
				_animator.ResetTrigger("WeaponShoot");
				_animator.ResetTrigger("WeaponShootAlt");
			}
			needSeccondAttack = false;
		}
	}

	public void SwitchAim(bool value)
	{
		if ((bool)_animator)
		{
			_animator.SetBool("WeaponAim", value);
		}
	}

	public void Init(PlayerMecanimWrapper value, float reloadTime, float timeBetweenShots, bool isPlayer = false)
	{
		_mecanimWrapper = value;
		_mecanimWrapper.eventHoldShoot -= ShootHold;
		_mecanimWrapper.eventAimMode -= SwitchAim;
		_mecanimWrapper.eventHoldShoot += ShootHold;
		_mecanimWrapper.eventAimMode += SwitchAim;
		isPlayerWeapon = isPlayer;
		if (_animator != null)
		{
			CancelReload();
			CalculateAnimationSpeed(reloadTime, timeBetweenShots);
			_animator.updateMode = AnimatorUpdateMode.UnscaledTime;
			if (baseOverrideController == null)
			{
				baseOverrideController = _animator.runtimeAnimatorController;
			}
			if (isPlayerWeapon && bonesWeapon == null)
			{
				bonesWeapon = new List<BonesPosition>();
				SkinnedMeshRenderer componentInChildren = _animator.GetComponentInChildren<SkinnedMeshRenderer>();
				BonesPosition item = default(BonesPosition);
				for (int i = 0; i < componentInChildren.bones.Length; i++)
				{
					item.position = componentInChildren.bones[i].localPosition;
					item.rotation = componentInChildren.bones[i].localRotation;
					bonesWeapon.Add(item);
				}
			}
			if (isPlayerWeapon && _animatorLeft != null && bonesWeaponLeft == null)
			{
				bonesWeaponLeft = new List<BonesPosition>();
				SkinnedMeshRenderer componentInChildren2 = _animatorLeft.GetComponentInChildren<SkinnedMeshRenderer>();
				BonesPosition item2 = default(BonesPosition);
				for (int j = 0; j < componentInChildren2.bones.Length; j++)
				{
					item2.position = componentInChildren2.bones[j].localPosition;
					item2.rotation = componentInChildren2.bones[j].localRotation;
					bonesWeaponLeft.Add(item2);
				}
			}
		}
		_timeBetweenShots = timeBetweenShots;
		_reloadTime = reloadTime;
	}

	public void SwitchFPSCameraMode(bool enableFPS)
	{
		if (FPSCamera.instance.enabled && !(_animator == null))
		{
			if (enableFPS && weaponOverrideControllerFPS != null)
			{
				SetAnimatorController(weaponOverrideControllerFPS);
			}
			else if (baseOverrideController != null && _animator.runtimeAnimatorController != baseOverrideController)
			{
				SetAnimatorController(baseOverrideController);
			}
		}
	}

	public void SetAnimatorController(RuntimeAnimatorController controller)
	{
		_animator.runtimeAnimatorController = controller;
		CalculateAnimationSpeed(_reloadTime, _timeBetweenShots);
	}

	private IEnumerator SetRuntimeAnimatorController(RuntimeAnimatorController overrideController)
	{
		while (true)
		{
			bool isActive = true;
			Transform tr = base.transform;
			while (tr != tr.root)
			{
				if (!tr.gameObject.activeSelf)
				{
					isActive = false;
					break;
				}
				tr = tr.parent;
			}
			if (isActive)
			{
				break;
			}
			yield return null;
		}
		_animator.runtimeAnimatorController = overrideController;
		CalculateAnimationSpeed(_reloadTime, _timeBetweenShots);
	}

	public void SetAnimator(Animator value)
	{
		_animator = value;
		_animator.logWarnings = false;
	}

	public Animator GetAnimator()
	{
		return _animator;
	}

	private void CalculateAnimationSpeed(float reloadTime, float timeBetweenShots)
	{
		float num = Mathf.Clamp(timeBetweenShots, 0.1f, 20f);
		float num2 = Mathf.Clamp(reloadTime, 0.1f, 20f);
		AnimationClip[] animationClips = _animator.runtimeAnimatorController.animationClips;
		AnimationClip[] array = animationClips;
		foreach (AnimationClip animationClip in array)
		{
			if (animationClip.name == "shoot")
			{
				num = Mathf.Clamp(animationClip.length, 0.1f, 20f);
			}
			if (animationClip.name == "reload")
			{
				num2 = Mathf.Clamp(animationClip.length, 0.1f, 20f);
			}
		}
		float value = Mathf.Clamp(num2 / reloadTime, 0.01f, 100f);
		float value2 = Mathf.Clamp(num / timeBetweenShots, 0.01f, 100f);
		_animator.SetFloat("ReloadSPEED", value);
		_animator.SetFloat("ShootSPEED", value2);
		if (_animatorLeft != null)
		{
			_animatorLeft.SetFloat("ReloadSPEED", value);
			_animatorLeft.SetFloat("ShootSPEED", value2);
		}
	}

	public float GetStateTime(string clipName, AnimatorOverrideController overrideController)
	{
		if (overrideController != null)
		{
			AnimationClipPair[] clips = overrideController.clips;
			AnimationClipPair[] array = clips;
			foreach (AnimationClipPair animationClipPair in array)
			{
				if (animationClipPair.overrideClip.name == clipName)
				{
					return animationClipPair.overrideClip.length;
				}
			}
		}
		return 0f;
	}

	public void PlayDemoAnim()
	{
		if (_animator != null)
		{
			_animator.SetTrigger("WeaponDemo");
		}
	}

	private void SetReloadSpeed(float val)
	{
		_animator.SetFloat("ReloadSPEED", val);
	}

	private void SetShootSpeed(float val)
	{
		_animator.SetFloat("ShootSPEED", val);
	}
}
